#include "client_mgr.h"
#include <server_share/msg_struct_login.h>
#include <game_share/utils.h>

using namespace NLNET;

namespace FES
{

void CClientMgr::init( NLNET::CCallbackServer* Clients )
{
	_clientMax        = IService::getInstance ()->ConfigFile.getVar ("ClientMax").asInt();
	_timeOut          = IService::getInstance ()->ConfigFile.getVar ("ClientTimeOut").asInt();
	_updateInterval   = IService::getInstance ()->ConfigFile.getVar ("ClientUpdateInterval").asInt();
	_asyncPlayerCount = IService::getInstance ()->ConfigFile.getVar ("AsyncLoginPlayerCountInterval").asInt();

	_Clients = Clients;
}

uint32 CClientMgr::currClients()
{
	return _clientMap.size();
}

CClient* CClientMgr::pushClient( DEF::UID uid, NLNET::TSockId from )
{
	if( _clientMap.size() > _clientMax )
	{
		return NULL;
	}

	CClient client;
	client.uid   = uid;
	client.con   = from;
	client.State = CClient::ONLINE;
	client.ticks = NLMISC::CTime::getLocalTime();

	std::pair<TClientMap::iterator, bool> res;
	res = _clientMap.insert(std::make_pair(uid,client));

	if ( res.second )
	{
		return &(res.first->second);
	}
	else
	{
		STOP("push error.");
		return NULL;
	}
}

CClient* CClientMgr::findClient(DEF::UID userId)
{
	TClientMap::iterator iter = _clientMap.find( userId );

	if(iter == _clientMap.end())
	{
		return NULL;
	}
	else
	{
		return &(iter->second);
	}
}

void CClientMgr::removeClient(DEF::UID userId)
{
	CMessage msgout("DC");
	msgout.serial(userId);
	NLNET::CUnifiedNetwork::getInstance()->send ("EGS", msgout);
	_clientMap.erase( userId );
}

void CClientMgr::disconnect(DEF::UID userId)
{
	TClientMap::iterator iter = _clientMap.find( userId );

	if(iter != _clientMap.end())
	{
		_Clients->disconnect( iter->second.con );
	}
}

bool CClientMgr::updateTime(DEF::UID userId)
{
	TClientMap::iterator iter = _clientMap.find( userId );

	if(iter == _clientMap.end())
	{
		return false;
	}
	else
	{
		iter->second.ticks = NLMISC::CTime::getLocalTime();
		return true;
	}
}

void CClientMgr::update( NLMISC::TTicks tick )
{
	if( tick - _preTicks > _updateInterval)
	{
		 TClientMap::iterator iter=_clientMap.begin();
		 while( iter != _clientMap.end() )  
		 {
			 if ( tick - iter->second.ticks > _timeOut )
			 {
				 _Clients->disconnect( iter->second.con );
				 _clientMap.erase(iter++);
			 }
			 else
			 {
				 ++iter;
			 }
		 }

		_preTicks = tick;
	}


	if( tick - _preAsyncPlayerCount > _asyncPlayerCount )
	{
		DEF::PLAYER_COUNT players = currClients();
		CMessage msgout("SET_FES_PLAYERS");
		msgout.serial(players);
		NLNET::CUnifiedNetwork::getInstance()->send ("LS", msgout);
		_preAsyncPlayerCount = tick;
	}
	
}

}

